1. Trang chủ
  2. » Công Nghệ Thông Tin

OReilly programming dot NET components 2nd edition jul 2005 ISBN 0596102070

1,2K 161 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 1.171
Dung lượng 5,88 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Programming .NET Components, Second Edition begins with a look at the fundamentals of component-oriented programming and then progresses from there.. Programming .NET Components, Second

Trang 1

maintainable, and robust components.

Following in the footsteps of its best-selling predecessor, Programming NET Components,

Second Edition has been updated to cover NET 2.0 It remains one of the few practical books available on this topic This invaluable resource is targeted at anyone who develops complex or enterprise-level applications with the NET platform an ever-widening market.

In fact, nearly two million Microsoft developers worldwide now work on such systems

Programming NET Components, Second Edition begins with a look at the fundamentals of

component-oriented programming and then progresses from there It takes the time to carefully examine how components can simplify and add flexibility to complex applications

by allowing users to extend their capabilities Next, the book introduces a variety of NET essentials, as well as NET development techniques Within this discussion on component development, a separate chapter is devoted to each critical development feature, including asynchronous calls, serialization, remoting, security, and more All the while, hazardous programming pitfalls are pointed out, saving the reader from experiencing them the hard way.

A NET expert and noted authority on component-oriented programming, Lowy uses his unique access to Microsoft technical teams to the best possible advantage, conveying detailed, insider information in easy-to-grasp, activity-filled language This hands-on approach is designed to allow individuals to learn by doing rather than just reading.

Indeed, after digesting Programming NET Components, Second Edition, readers should be

able to start developing NET components immediately

Programming NET Components, Second Edition is the consummate introduction to the

Microsoft NET Framework the technology of choice for building components on Windows platforms From its many lessons, tips, and guidelines, readers will learn how to use the NET Framework to program reusable, maintainable, and robust components.

Following in the footsteps of its best-selling predecessor, Programming NET Components,

Trang 2

Second Edition has been updated to cover NET 2.0 This invaluable resource is targeted at anyone who develops complex or enterprise-level applications with the NET platform an ever-widening market.

Trang 7

by Juval Löwy

Copyright © 2005, 2003 O'Reilly Media, Inc All rights reserved.Printed in the United States of America

Published by O'Reilly Media, Inc., 1005 Gravenstein HighwayNorth, Sebastopol, CA 95472

O'Reilly Media, Inc books may be purchased for educational,business, or sales promotional use Online editions are also

available for most titles (safari.oreilly.com) For more

Trang 8

Programming NET Components, Second Edition, the image of a

land hermit crab, and related trade dress are trademarks of

O'Reilly Media, Inc Microsoft, the NET logo, Visual Basic NET,Visual Studio NET, ADO.NET, Windows, and Windows 2000 areregistered trademarks of Microsoft Corporation

Many of the designations used by manufacturers and sellers todistinguish their products are claimed as trademarks Wherethose designations appear in this book, and O'Reilly Media, Inc.was aware of a trademark claim, the designations have beenprinted in caps or initial caps

While every precaution has been taken in the preparation of thisbook, the publisher and author assume no responsibility for

errors or omissions, or for damages resulting from the use ofthe information contained herein

ISBN: 0-596-00762-0

[M]

Trang 9

To my daughter, Abigail

Trang 10

I've been fortunate in my career to have lived through mostgenerations of Microsoft component technologies In the mid-1990s, I developed dynamic link libraries and exported theirfunctions, and I used Microsoft Foundation Class (MFC)

extension DLLs to expose classes I experienced firsthand theenormous complexity involved in managing a set of interactingapplications comprised of 156 DLLs and deployed as a singleunit, as well as the maintenance and versioning issues raised bytheir use of ordinal numbers I helped design COM-like solutions

to those problems, and I remember when I first heard aboutCOM and when I generated my first GUID using a command-line utility

I learned how to write class factories and IDL interfaces longbefore the release of ATL, and I tried to use RPC before DCOMabstracted it away I designed component-based applicationsusing COM and experienced what it takes to share design ideaswith other developers who aren't familiar with its requirements

I programmed with MTS and learned the workarounds involved

in its use, and I marveled at the elegance and usefulness ofCOM+ when it came to architecting large-scale enterprise

frameworks

My understanding of component-oriented programming has

evolved and grown over that time, just as the component-basedtechnologies themselves have done I have often asked myselfwhat the fundamental principles of using components are, and

in what ways they differ from traditional object-oriented

programming I have tried to learn from my mistakes and toabstract and generalize the good ideas and techniques I haveencountered or developed on my own I believe that I have

identified some core principles of component-oriented designthat transcend any technologies available today and that result

Trang 11

With the advent of the NET Framework, Windows developersfinally have at their disposal a first-class technology that aims

based applications .NET is the result of much soul-searching byMicrosoft, and in my view it improves on the deficiencies of

at simplifying the task of developing and deploying component-previous technologiesespecially COM It incorporates and

enforces a variety of proven methodologies and approaches,while retaining their core benefits

To me, NET is fundamentally a component technology that

provides an easy and clean way to generate binary components,

in compliance with what I regard as sound design principles NET is engineered from the ground up to simplify componentdevelopment and deployment, and to support interoperabilitybetween programming languages It is highly versatile, and

.NET components are used for building a wide range of

component-based applications, from standalone desktop

applications to web-based applications and services

Of course, NET is more than just a component technology; it'sactually a blanket name for a set of technologies

In the context of this book, whenever I use the term ".NET," I'm referring to the NET Framework in general and the component technology it embodies in particular.

.NET provides several specialized application frameworks,

including Windows Forms for rich Windows clients, ADO.NET fordata access, ASP.NET for web applications, and web services forexposing and consuming remote services that use the SOAPand other XML-based protocols Visual Studio 2005 supports the

Trang 12

languages as well You can host NET applications in Windows or

in SQL Server 2005 Microsoft server products will increasinglysupport NET-connected applications in the coming years, andfuture versions of Windows will be heavily based on NET

Trang 13

This book covers the topics and teaches you the skills you need

to design and develop component-based NET applications

However, to make the most of NET, it helps to know its originsand how it improves on the shortcomings of past technologies

In addition to showing you how to perform certain tasks, thebook often explains the rationale behind them in terms of theprinciples of component-oriented programming Armed withsuch insights, you can optimize your application design for

maintainability, extensibility, reusability, and productivity Whilethe book can be read without prior knowledge of COM, I

occasionally use COM as a point of reference when it helps

explain why NET operates the way it does

In this book, you'll learn not only about NET component

programming and the related system issues, but also aboutrelevant design options, tips, best practices, and pitfalls Thebook avoids many implementation details of NET and largelyconfines its coverage to the possibilities and the practical

aspects of using NET as a component technology: how to applythe technology and how to choose among the available designand programming models In addition, the book contains manyuseful utilities, tools, and helper classes I've developed since.NET was introduced five years ago These are aimed at

increasing your productivity and the quality of your NET

components After reading this book, you will be able to startdeveloping NET components immediately, taking full advantage

of the NET development infrastructure and application

frameworks The book makes the most of what both NET 1.1and NET 2.0 have to offer

Here is a brief summary of the chapters and appendixes in thisbook:

Trang 14

Provides the basic terminology used throughout the book.This chapter contrasts object-oriented programming withcomponent-oriented programming and then enumerates theprinciples of component-oriented programming These

principles are the "why" behind the "how" of NET, and

understanding them is a prerequisite to correctly buildingcomponent-based applications

Chapter 2, NET Component-Oriented Programming Essentials

Describes the elements of NET, such as the Common

Language Runtime (CLR), NET programming languages,the code-generation process, assemblies, and building andcomposing those assemblies This chapter ends by

explaining how NET maintains binary compatibility betweenclients and components and discussing the implications ofthis solution for the programming model If you are alreadyfamiliar with the fundamentals of the NET Framework, both

in version 1.1 and version 2.0, feel free to skim over or

entirely skip this chapter

Chapter 3, Interface-Based Programming

Examines working with interfaces This chapter explainshow to separate an interface from its implementation in.NET, how to implement interfaces, and how to design andfactor interfaces that cater to reusability, maintainability,and extensibility

Chapter 4, Lifecycle Management

Trang 15

programming model This chapter explains the underlying.NET garbage-collection mechanism and shows componentdevelopers how to dispose of resources held by instances of

a component

Chapter 5, Versioning

Begins by describing the NET version-control policy and theways you can deploy and share its components After

dealing with the default policy, this chapter shows how toprovide custom version binding and resolution policies toaddress application- or even machine-specific needs Thechapter also discusses how to develop applications that

support multiple versions of NET itself

Chapter 6, Events

Shows how to publish and subscribe to events in a

component-based application After discussing the built-insupport provided by NET, this chapter presents a number ofbest practices and utilities that are designed to make themost of the basic event support and to improve it

Chapter 7, Asynchronous Calls

Describes NET's built-in support for invoking asynchronouscalls on components, the available programming models,their trade-offs, when to use them, and their pitfalls

Trang 16

Explains in depth how to build multithreaded components

No modern application is complete without multiple threads,but multithreading comes with a hefty pricethe need to

synchronize access to your components This chapter showshow to create and manage threads and how to synchronizeaccess to objects, using both the little-known

synchronization domains and the manual synchronizationlocks The chapter ends with a rundown of various

multithreading services in NET, such as the thread pool andtimers

hierarchy You will also see how to improve on the basicserialization offering using generics

Chapter 10, Remoting

Demystifies NET support for remote calls This chapter

starts by explaining application domains and the availableremote object types and activation modes After a

discussion of the remoting architecture, it shows how to set

up a distributed component-based NET application, bothprogrammatically and administratively The chapter

concludes by explaining how to manage the lifecycle of

remote objects using leasing and sponsorship Even if you

do not intend to use remoting, this chapter provides a lot of

Trang 17

productivity-oriented custom services

Chapter 12, Security

Addresses the rich topic of NET code-access security

Unlike Windows security, NET security is component-based,not user-based As such, it opens new possibilities for

component developers This chapter shows how to

administer security using the NET configuration tool andhow to provide additional security programmatically It alsocovers how to use NET role-based security and how to

Trang 18

Presents a set of interacting helper classes and controls thatenable a Windows Forms application to use the ASP.NET 2.0credential-management infrastructure with the same ease

Appendix D, Generics

Briefly explains generics, which are some of the most

powerful and useful features of NET 2.0 This book makesextensive use of generics in almost every chapter If you areunfamiliar with generics, I recommend that you read thisappendix before the rest of the chapters More advancedaspects of generics are covered in the chapters themselves

Appendix E, C# Coding Standard

Presents a consolidated list of all the best practices and dosand don'ts mentioned thought the book The standard is allabout the "how" and the "what," not the "why"; the

rationale behind it is found in the rest of the book The

standard is based on the IDesign Coding Standard, which

Trang 19

has become the de facto industry coding standard for NETdevelopment The IDesign standard in turn was based onthe first edition of this book.

Trang 20

I assume that you, the reader, are an experienced developerand that you feel comfortable with object-oriented conceptssuch as encapsulation and inheritance I also assume that youhave basic familiarity with either C# or Visual Basic, both inversions 1.1 and 2.0 of the languages Although the book usesC# for the most part, it's just as pertinent to Visual Basic 2005developers In cases in which the translation from C# to VisualBasic 2005 isn't straightforward or when the two languagesdiffer significantly, I've provided either matching Visual Basic

2005 sample code or an explicit note

If you're experienced with COM, this book will port your COMunderstanding to NET If you've never used COM before, you'llfind the coverage of the principles of component-oriented

programming especially useful

Trang 21

Whenever I wish to make a point in a code sample, I do so withthe static Assert method of the Debug class:

int number = 1+2;

Debug.Assert(number == 3);

exception when the statement is false

Trang 22

This book follows the recommended naming guidelines andcoding style presented in Appendix E Whenever it deviatesfrom that standard, it is likely the result of space or line-lengthconstraints With respect to naming conventions, I use "Pascalcasing" for public member methods and properties; this meansthe first letter of each word in the name is capitalized For localvariables and method parameters I use "Camel casing," in

Trang 23

Please address comments and questions concerning this book tothe publisher:

http://www.oreilly.com/catalog/pnetcomp2

To comment or ask technical questions about this book, sendemail to:

Trang 24

When you see a Safari® Enabled icon on the cover ofyour favorite technology book, that means the book is availableonline through the O'Reilly Network Safari Bookshelf

Safari offers a solution that's better than e-books It's a virtuallibrary that lets you easily search thousands of top tech books,cut and paste code samples, download chapters, and find quickanswers when you need the most accurate, current information.Try it free for at http://safari.oreilly.com

Trang 25

Shortly after the unveiling of NET in the summer of 2000, JohnOsborn from O'Reilly and I started discussing a book that wouldexplore the uses of NET as a component-based application

development platform The first edition of the book was the

result of John's sponsorship and support Over the last threeyears I have worked closely with Microsoft as part of the

The following friends and colleagues helped with the first edition

of the book: Chris W Rea, Billy Hollis, Jimmy Nilsson, NicholasPaldino, Ingo Rammer, and Pradeep Tapadiya The following

provided valuable feedback for the second edition: Sam Gentile,Richard Grimes, Norman Headlam, Benjamin Mitchell, and BrianNoyes All of them gave generously of their time In particular, I

am grateful to Nicholas Paldino for his help with the second

edition Nick's knowledge of the framework is unsurpassed, andhis meticulous attention to details contributed greatly to thequality and cohesiveness of this book

Finally, my family Many thanks to my wife Dana, who knows alltoo well that writing a book entails time away from the familybut still encourages me to write I dedicate this book to my five-year-old daughter Abigail She has her own computer now,

where she enthusiastically plays her Princesses games I amwaiting for the day I can talk with her about the principles ofbuilding systems and services out of components I think I amgoing to start with interfaces

Trang 26

Chapter 1 Introducing Component-Oriented Programming

Over the last decade, component-oriented programming hasestablished itself as the predominant software developmentmethodology The software industry is moving away from giant,monolithic, hard-to-maintain code bases Practitioners havediscovered that by breaking down a system into binary

components, they can attain much greater reusability,

extensibility, and maintainability These benefits can, in turn,lead to faster time to market, more robust and highly scalableapplications, and lower development and long-term

maintenance costs Consequently, it's no coincidence that

component-oriented programming has caught on in a big way

Several component technologies, such as DCOM, CORBA, andJavaBeans? give programmers the means to implement

component-oriented applications However, each technology hasits drawbacks; for example, DCOM is too difficult to master, andthe Java? Virtual Machine (JVM) doesn't support interoperationwith other languages

.NET is the latest entrant to the field, and as you will see later

in this chapter and in the rest of this book, it addresses the

requirements of component-oriented programming in a waythat is both unique and vastly easier to use These

improvements are of little surprise, because the NET architectswere able to learn from both the mistakes and successes of

previous technologies

In this chapter, I'll define the basic terms of component-oriented programming and summarize its core principles andtheir corresponding benefits These principles apply throughoutthe book, and I'll refer to them in later chapters when

describing the motivations for particular NET design patterns

Trang 27

Component-oriented programming is different from object-oriented programming, although the two methodologies do

have things in common You could say that component-orientedprogramming sprouted from the well of object-oriented

programming methodologies Therefore, this chapter also

contrasts component-oriented programming and object-orientedprogramming, while briefly discussing NET as a componenttechnology

Trang 28

The term component is probably one of the most overloaded

and therefore most confusing terms in modern software

engineering, and the NET documentation has its fair share ofinconsistency in its handling of this concept The confusion

arises in deciding where to draw the line between a class thatimplements some logic, the physical entity that contains it

(typically a dynamic link library, or DLL), and the associatedlogic used to deploy and use it, including type information,

have to make any assumptions about such details An object is

Trang 29

class The object is also sometimes referred to as the server,

because the relationship between client and object is often

called the client/server model In this model, the client creates

an object and accesses its functionality via a publicly availableentry point, traditionally a public method but preferably an

interface, as illustrated by Figure 1-1 Note that in the figure anobject is an instance of a component; the "lollipop" denotes aninterface

Figure 1-1 A client accessing an object

I'll discuss NET interface-based programming in detail in

Chapter 3 For now, it's important to emphasize that while NETdoesn't force you to do interface-based programming, as youwill see shortly, you should strive to do so whenever possible

To emphasize this practice, I represent the entry points of thecomponents that appear in my design diagrams as interfacesrather than mere public methods

Although the object depicted in Figure 1-1 is drawn like a COM object, with its characteristic lollipop icon, use of this icon isn't restricted to COMit is accepted as the standard UML symbol for an interface, regardless of the component technology and development platform that implement it.

Trang 30

hiding of information from the client The less a client knowsabout the way an object is implemented, the better The morethe details of an implementation are encapsulated, the greater

is the likelihood that you can change a method or property

without affecting the client code Interfaces maximize

encapsulation because the client interacts with an abstract

service definition instead of an actual object Encapsulation iskey to successfully applying both object-oriented and

component-oriented methodologies

Another important concept that originated with object-oriented

programming is polymorphism Two objects are said to be

polymorphic with respect to each other when both derive from acommon base type (such as an interface) and implement theexact set of operations defined by that base type If a client iswritten to use the operations of a base type, the same clientcode can interact with any object that is polymorphic with thatbase type When polymorphism is used properly, changing fromone object to another has no effect on the client; it simplifiesmaintenance of the application to which the client and objectbelong

Trang 31

interchangeable code modules that work independently anddon't require you to be familiar with their inner workings to usethem

1.2.1 Building Blocks Versus Monolithic

Applications

The fundamental difference between the two methodologies isthe way in which they view the final application In the

traditional object-oriented world, even though you may factorthe business logic into many fine-grained classes, once thoseclasses are compiled, the result is monolithic binary code Allthe classes share the same physical deployment unit (typically

an EXE), process, address space, security privileges, and so on

If multiple developers work on the same code base, they have

to share source files In such an application, a change made toone class can trigger a massive re-linking of the entire

application and necessitate retesting and redeployment of allthe other classes

On the other hand, a component-oriented application comprises

a collection of interacting binary application modulesthat is, itscomponents and the calls that bind them (see Figure 1-2)

Trang 32

A particular binary component may not do much on its own.Some may be general- purpose components, such as

communication wrappers or file-access components Othersmay be highly specialized and developed specifically for the

The motivation for breaking down a monolithic application intomultiple binary components is analogous to that for placing thecode for different classes into different files By placing the codefor each class in an application into its own file, you loosen thecoupling between the classes and the developers responsible forthem If you make a change to one class, although you'll have

to re-link the entire application, you'll only need to recompilethe source file for that class

However, there is more to component-oriented programmingthan simple software project management Because a

Trang 33

component implementation, changes are contained to that

component only No existing client of the component requiresrecompilation or redeployment Components can even be

provide them in new components, without having to touch

existing components not affected by the new requirements

These factors enable component-oriented programming to

reduce the cost of long-term maintenance, a factor essential toalmost any business, which helps explain the widespread

adoption of component technologies

Component-oriented applications usually have a faster time tomarket, because you can select from a range of available

1.2.2 Interfaces Versus Inheritance

Another important difference between object-oriented and

component-oriented applications is the emphasis the two

models place on inheritance and reuse models

Trang 34

to approximate as closely as possible the business problem

being solved You reuse existing code by inheriting it from anexisting base class and specializing its behavior The problem isthat inheritance is a poor way to achieve reuse When you

derive a subclass from a base class, you must be intimatelyaware of the implementation details of the base class For

example, what is the side effect of changing the value of a

member variable? How does it affect the code in the base class?Will overriding a base class method and providing a differentbehavior break the code of clients that expect the base

behavior?

This form of reuse is commonly known as white-box reuse,

because you are required to be familiar with the details of thebase class implementation White-box reuse simply doesn't

allow for economy of scale in large organizations' reuse

programs or easy adoption of third-party frameworks

Component-oriented programming promotes black-box reuse

instead, which allows you to use an existing component withoutcaring about its internals, as long as the component complieswith some predefined set of operations or interfaces Instead ofinvesting in designing complex class hierarchies, component-oriented developers spend most of their time factoring out theinterfaces used as contracts between components and clients

.NET does allow components to use inheritance of implementation, and you can certainly use this technique to develop complex class

hierarchies However, you should keep your class hierarchies as simple and as flat as possible, and focus instead on factoring interfaces Doing

so promotes black-box reuse of your component instead of white-box reuse via inheritance.

Trang 35

design patterns for dealing with the runtime aspects of the

application, such as multithreading and concurrency

management, security, distributed applications, deployment, orversion control Object-oriented developers are more or less left

to their own devices when it comes to providing infrastructurefor handling these common requirements As you will see

throughout this book, NET supports you by providing a superbcomponent-development infrastructure Using NET, you canfocus on the business problem at hand instead of the softwareinfrastructure needed to build the solution

Trang 36

Programming

Component-oriented programming requires both systems thatsupport the approach and programmers that adhere to its

discipline and its core principles However, it's often hard to tellthe difference between a true principle and a mere feature ofthe component technology being used As the supporting

technologies become more powerful, no doubt software

engineering will extend its understanding of what constitutescomponent-oriented programming and embrace new ideas, andthe core principles will continue to evolve The most importantprinciples of component-oriented programming include:

Trang 37

Implementation

The fundamental principle of component-oriented programming

is that the basic unit in an application is a binary-compatibleinterface The interface provides an abstract service definitionbetween a client and the object This principle contrasts withthe object-oriented view of the world, which places the object,

rather than its interface, at the center An interface is a logical grouping of method definitions that acts as the contract

between the client and the service provider Each provider isfree to provide its own interpretation of the interfacethat is, itsown implementation The interface is implemented by a black-box binary component that completely encapsulates its interior

This principle is known as separation of interface from

implementation.

To use a component, the client needs only to know the interfacedefinition (i.e., the service contract) and to be able to access abinary component that implements that interface This extralevel of indirection between the client and the object allows oneimplementation of an interface to be replaced by another

without affecting the client code The client doesn't need to berecompiled to use a new version Sometimes the client doesn'teven need to be shut down to do the upgrade Provided theinterface is immutable, objects implementing the interface arefree to evolve, and new versions can be introduced smoothlyand easily To implement the functionality promised by an

interface inside a component, you use traditional object-oriented methodologies, but the resulting class hierarchies areusually simpler and easier to manage

Interfaces also facilitate reuse In object-oriented programming,the basic unit of reuse is the object In theory, different clientsshould be able to use the same object Each reuse instance

saves the reusing party the amount of time and effort that

Trang 38

initiatives have the potential for significant cost reductions andreduced product-development cycle time One reason why theindustry adopted object-oriented programming so avidly was itsdesire to reap the benefits of reuse

In reality, however, objects are rarely reusable They are oftenspecific to the problems and particular contexts for which theywere developed, and unless the objects are "nuts and bolts"that

is, simple and genericthey can't be reused even in very similarcontexts This is also true in many engineering disciplines,

including mechanical and electrical engineering For example,consider the computer mouse you use with your workstation.Each part of this mouse is designed and manufactured

specifically for your make and model For reasons of brandingand electronics specifics, parts such as the body case can't beused in the manufacturing of any other type of mouse (evenvery similar ones), whether made by the same manufacturer orothers However, the interface between mouse and human hand

is well defined, and any human (not just yourself) can use themouse Similarly, the typical USB interface between mouse andcomputer is well defined, and your mouse can plug into almostany computer adhering to that interface The basic units of

reuse in the computer mouse are the interfaces with which themouse complies, not the mouse parts themselves

In component-oriented programming, the basic unit of reuse isthe interface, not a particular component By separating

interfaces from implementation in your application, and usingpredefined interfaces or defining new interfaces, you enablethat application to reuse existing components and enable reuse

of your new components in other applications

1.3.2 Binary Compatibility Between Client and Server

Trang 39

code must interact at runtime with exactly what it expects asfar as the binary layout in memory of the component entry

points This binary compatibility is the basis for the contractbetween the component and the client As long as the new

version of the component abides by this contract, the client isn'taffected In Chapter 2, you will see how NET provides binarycompatibility

1.3.3 Language Independence

Unlike in traditional object-oriented programming, in

component-oriented programming, the server is developed

independently of the client Because the client interacts with theserver only at runtime, the only thing that binds the two is

Trang 40

be in the same process (e.g., Process 1 on Machine A), in

different processes on the same machine (e.g., Process 1 andProcess 2 on Machine A), on different machines in the samelocal network (e.g Machine B), or even on different machinesacross the Internet (e.g., Machine C)

Figure 1-3 With location transparency, the client

is oblivious to the actual object location

Ngày đăng: 26/03/2019, 16:32

TỪ KHÓA LIÊN QUAN